import java.io.File

import akka.actor.{Actor, ActorRef, ActorSystem, PoisonPill, Props}

import scala.concurrent.duration._
import scala.io.Source._


object ReadFile {

  class PrintFile(cl: ActorRef) extends Actor {
    val p = "^\\s*\\*|/".r

    override def receive: Receive = {
      case f: File => {
        val lines = fromFile(f, "utf-8").getLines().filter(l => l.trim.length > 5).length
        println("find file " + f.getPath + " lines : " + lines)

        cl ! lines
      }
      case s: String => println("add success : " + s)
    }

    override def preStart(): Unit = {
      println("ReadFile prestart ....")
      super.preStart()
    }

    override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
      println("ReadFile preRestart ....")
      super.preRestart(reason, message)
    }

    override def postStop(): Unit = {
      println("ReadFile postStop ...")
      super.postStop()
    }

    override def postRestart(reason: Throwable): Unit = {
      println("ReadFile postRestart ....")
      super.postRestart(reason)
    }
  }

  class CountLines extends Actor {
    var lines = 0

    override def receive: Receive = {
      case x: Int => {
        lines += x
        sender() ! ("lines = " + lines)
      }
      case "get" => println("lines " + lines)
    }

    override def preStart(): Unit = {
      println("CountLines prestart ....")
      super.preStart()
    }

    override def preRestart(reason: Throwable, message: Option[Any]): Unit = {
      println("CountLines preRestart ....")
      super.preRestart(reason, message)
    }

    override def postStop(): Unit = {
      println("CountLines postStop ...")
      super.postStop()
    }

    override def postRestart(reason: Throwable): Unit = {
      println("CountLines postRestart ....")
      super.postRestart(reason)
    }
  }

  class FindFile(cl: ActorRef) extends Actor {
    def find(dir: File, root: File): Unit = {
      val fs = dir.listFiles()
      fs.filter(x => x.isDirectory).foreach(x => find(x, root))
      fs.filter(x => {
        x.isFile && x.getName.endsWith(".java")
      }).foreach(f => context.actorOf(Props(classOf[PrintFile], cl)) ! f)

      //over
      if (dir.getPath.equals(root.getPath)) {
        println("scan file over.....")
        println(cl ! "get")
//        cl ! PoisonPill
      }
    }

    override def receive: Receive = {
      case path: String => {
        println("receive path : " + path)
        val root = new File(path)
        if (root.isDirectory) {
          println(root.getPath + " is dir")
          find(root, root)
        } else {
          println("error path")
        }
      }
      case _ => println("undefined path")
    }
  }

  def main(args: Array[String]): Unit = {
    val dir = "/home/lzt/workspace/javaee/bgpt"
    val system = ActorSystem("findfile")
    val countLines = system.actorOf(Props[CountLines])
    val findFile = system.actorOf(Props(classOf[FindFile], countLines))
    findFile ! dir

    import system.dispatcher
    system.scheduler.scheduleOnce(5000 millis) {
      findFile ! dir
    }
  }

}
